/**
  ******************************************************************************
  * @file    input_output.h
  * @author  ashuai0110
  * @version V2.3
  * @date    2024-07-01
  * @brief   IO输入输出操作
  *          (输入可以设置各边沿触发时间,输出可以设置各边沿保持时间)
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  ******************************************************************************
  */

#ifndef __INPUT_OUTPUT_H
#define __INPUT_OUTPUT_H

#ifdef __cplusplus
extern "C" {
#endif

/* 包含头文件-----------------------------------------------------------------*/
#include "common_include.h"

/**
 * @addtogroup modules
 * @{
 */

/**
 * @addtogroup input_output
 * @{
 */

/* 宏定义---------------------------------------------------------------------*/
/**
 * @defgroup input_output_global_macros input output global macros
 * @{
 */

/**
 * @defgroup io_run_flg input output run flag
 * @{
 */
#define IO_RUN_STOP                     (0u) /*!< 不运行*/
#define IO_RUN_START                    (1u) /*!< 运行*/
/**
 * @}
 */

/**
 * @defgroup io_dir io dir
 * @{
 */
#define IO_DIR_OUT                      (0u) /*!< 输出方向 */
#define IO_DIR_IN                       (1u) /*!< 输入方向 */
/**
 * @}
 */

/**
 * @defgroup in_edge_type input edge type
 * @{
 */
#define IN_EDGE_NONE                    (0u) /*!< 输入无边沿变化 */
#define IN_EDGE_RISING                  (1u) /*!< 输入上升沿 */
#define IN_EDGE_FALLING                 (2u) /*!< 输入下降沿 */
/**
 * @}
 */

/**
 * @defgroup out_cycle_state output cycle state
 * @{
 */
#define OUT_CYCLE_END                   (0u) /*!< 输出一个周期结束 */
#define OUT_CYCLE_ING                   (1u) /*!< 输出一个周期进行中 */
/**
 * @}
 */

/**
 * @}
 */

/* 类型定义-------------------------------------------------------------------*/
/**
 * @defgroup input_output_global_types input output global types
 * @{
 */

/**
  * @brief  IO读函数(输入方向) / IO写函数(输出方向)
  *
  * @param  level : 无意义 / 写IO的电平(0/1)
  *
  * @retval 读取到的电平(0/1) / 无意义
  */
typedef uint8_t (* io_rw_fn_t)(uint8_t level);

/**
  * @brief  IO输入触发回调函数(输入方向) / IO输出完成回调函数(输出方向)
  *
  * @param  edge : 触发的边沿类型(IO_RISING/IO_FALLING) / 无意义
  *
  * @retval None
  */
typedef void (* io_cb_fn_t)(uint8_t edge);

/**
  * @brief  IO操作 structure definition
  */
typedef struct input_output{
    volatile uint32_t ticks;    /*!< 基础计数值 */
    uint32_t risingTicks;       /*!< 上升沿输入触发计数值(输入方向) / 上升沿输出保持计数值(输出方向) */
    uint32_t fallingTicks;      /*!< 下降沿输入触发计数值(输入方向) / 下降沿输出保持计数值(输出方向) */
    uint8_t level : 1;          /*!< 默认电平 */
    uint8_t run : 1;            /*!< 运行标志 @ref io_run_flg */
    uint8_t dir : 1;            /*!< IO方向 @ref io_dir */
    uint8_t state : 3;          /*!< 状态机索引暂存 */
    uint8_t edge : 2;           /*!< 输入边沿暂存 @ref in_edge_type */
    io_rw_fn_t rwFn;            /*!< IO读写函数 */
    io_cb_fn_t callbackFn;      /*!< IO回调函数 */
    struct input_output *pNext; /*!< 链表下一节点 */
} io_t;

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 函数原型-------------------------------------------------------------------*/
/**
 * @addtogroup input_output_global_functions
 * @{
 */

uint8_t io_init(io_t *_io, io_rw_fn_t rwFn, io_cb_fn_t callbackFn, uint8_t dir, uint8_t run);
void io_de_init(io_t *_io);

void io_update_ticks(io_t *_io, uint32_t risingTicks, uint32_t fallingTicks);

void io_poll(void);

/* list interface */
uint8_t io_insert(io_t *_io);
uint8_t io_pending(io_t *_io);

/* set/get interface */
void io_set_rising_ticks(io_t *_io, uint32_t risingTicks);
uint32_t io_get_rising_ticks(io_t *_io);
void io_set_falling_ticks(io_t *_io, uint32_t fallingTicks);
uint32_t io_get_falling_ticks(io_t *_io);
void io_set_run(io_t *_io, uint8_t runFlg);
uint8_t io_get_run(io_t *_io);

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* input_output.h */
